package testerbeans;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlInputHidden;
import javax.faces.context.FacesContext;

import controllers.InterviewController;
import controllers.AuthentificationController;
import controllers.MenuController;

import statefulbeans.TesterInterviewBeanRemote;
import testutil.ScoreComputationBeanRemote;

import dao.CandidateDAORemote;
import dao.InterviewDAORemote;
import dao.TestQuestionDAORemote;
import dto.CandidateViewDto;
import dto.InterviewViewDto;
import dto.TestQuestionDTO;

@ManagedBean
@SessionScoped
public class ViewCandidatesBean implements Serializable {

	// bean for displaying information for logged tester
	private static final long serialVersionUID = 1L;
	@EJB
	CandidateDAORemote candidateBean;
	@EJB
	InterviewDAORemote interviewBean;
	@EJB
	TesterInterviewBeanRemote testerBean;
	@EJB
	TestQuestionDAORemote testQuestionBean;
	@EJB
	ScoreComputationBeanRemote scoreBean;
	@ManagedProperty(value="#{menuController}")
	private MenuController menuController;
	@ManagedProperty(value = "#{emailBean}")
	private EmailBean emailBean;
	@ManagedProperty(value = "#{interviewController}")
	private InterviewController interviewController;
	@ManagedProperty(value = "#{correctTestBean}")
	private CorrectTestBean correctBean;
	private ArrayList<CandidateViewDto> candidates = new ArrayList<CandidateViewDto>();
	private ArrayList<CandidateViewDto> candidatesById = new ArrayList<CandidateViewDto>();
	@ManagedProperty(value = "#{authentificationController}")
	private AuthentificationController authentificationController;
	@ManagedProperty(value = "#{testDetailsBean}")
	private TestDetailsBean testDetailsBean;
	private int employeeid;
	private HtmlDataTable dataTable;
	private InterviewViewDto test= new InterviewViewDto();
	private HtmlDataTable mainTable;
	private HtmlDataTable testNameTable;
	private CandidateViewDto candidate;
	private ArrayList<InterviewViewDto> intervShowCandidate = new ArrayList<InterviewViewDto>();
	private HtmlInputHidden dataItemId = new HtmlInputHidden();
	

	public ViewCandidatesBean() {

	}

	public void setCandidates(ArrayList<CandidateViewDto> candidates) {
		this.candidates = candidates;
	}

	// initialize candidates
	@PostConstruct
	public void init() {
		employeeid = authentificationController.getEmployeeId();
		testerBean.setEmployeeid(employeeid);
		//get all candidates from database
		candidates = (ArrayList<CandidateViewDto>) candidateBean.getCandidates(employeeid);	
		
	}

	

	// if View button was pressed
	public void view() {
		//get selected interview
		test = ((InterviewViewDto) dataTable.getRowData());	
		for (CandidateViewDto c:candidates)
			if (c.getInterviews().contains(test)) candidate= c;
		System.out.println("obtained candidate: "+candidate.getName()+" with interviews: "+candidate.getInterviews().size());
		try {
			List<TestQuestionDTO> answers = testQuestionBean
					.getInterviewQuestions(test.getId());
			//for each question
			for (TestQuestionDTO a : answers) {
				//get the correct answer and the candidate's answer
				String correctAnswer = Integer.toString(a.getQuestion().getCorrectAnswers());
				String candidateAnswer = Integer.toString(a.getCandidateAnswer());

				//compute the score
				float score = scoreBean.getPointsForQuestion(correctAnswer,candidateAnswer);
				
				//set images for each answer based on the correctness of the candidate's answer
				a.getQuestion().setImage1(testQuestionBean.returnImageForAnswer(correctAnswer,candidateAnswer, "1"));
				a.getQuestion().setImage2(testQuestionBean.returnImageForAnswer(correctAnswer,candidateAnswer, "2"));
				a.getQuestion().setImage3(testQuestionBean.returnImageForAnswer(correctAnswer,candidateAnswer, "3"));
				a.getQuestion().setImage4(testQuestionBean.returnImageForAnswer(correctAnswer,candidateAnswer, "4"));
				a.setScore(score);
			}
			
			//initialize the correctBean
			test.setTestQuestions(answers);
			correctBean.setDate(format(test.getDate()));
			correctBean.setName(test.getCandidate().getFirstName() + " "+ test.getCandidate().getLastName());
			correctBean.setInterview(test);
			correctBean.setTotalScore(Math.round(scoreBean.computeTotalScore(test.getId())/answers.size()*100));
			correctBean.setEmployeeid(employeeid);
			correctBean.setCandidate(candidate);
			
			if (test.getTestQuestions().size() > 0) {
				correctBean.setShowTable(true);
			} else{
				correctBean.setShowTable(false);
				/*test.setView(true);
				test.setDelete(true);
				test.setButDel("buttonDis");
				test.setButView("buttonDis");	
				*/
			}
			
			
			try{
			correctBean.setComment(interviewBean.getComment(test.getId()));
			
			}catch (Exception ex){}

			dataItemId.setValue(test);
			//redirect to testerview page
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/testerview.xhtml");
		} catch (Exception e1) {
			e1.printStackTrace();
		}

	}

	// if delete button was pressed
	public void delete() {
		//get selected interview
		test = (InterviewViewDto) dataTable.getRowData();
		
		//set buttons
		test.setSend(true);
		test.setDelete(true);
		test.setButSend("buttonDis");
		test.setButDel("buttonDis");
		dataItemId.setValue(test);
		
		//remove interview from candidate's list
		candidate = (CandidateViewDto) mainTable.getRowData();
		candidate.getInterviews().remove(test);
		
		List<CandidateViewDto> can= new ArrayList<CandidateViewDto>();
		for (CandidateViewDto c:candidates)
			if (c.getId()!=candidate.getId())
				can.add(c);
			else can.add(candidate);
		
		//remove interview from database
		interviewBean.deleteInterview(test.getId());

	}

	public int computeDuration(InterviewViewDto test) {

		String[] tokens1 = test.getStartTime().split(":");
		String[] tokens2 = test.getEndTime().split(":");

		int hours = Integer.parseInt(tokens2[0]) - Integer.parseInt(tokens1[0]);
		int minutes = Integer.parseInt(tokens2[1])
				- Integer.parseInt(tokens1[1]) + hours * 60;

		return minutes;
	}

	// if Send Email button was clicked
	public void sendEmail() {
		//get selected interview
		test = (InterviewViewDto) dataTable.getRowData();
		/*//set buttons
		test.setDelete(true);
		test.setSend(true);
		test.setView(false);
		test.setButDel("buttonDis");
		test.setButSend("buttonDis");
		test.setButView("button");*/
		

		try{	
			
		String link= (String)candidateBean.getLink(test.getCandidate().getId());
		System.out.println("link1: "+link);
		if (link== null)
			link=(String)candidateBean.generateLink(test.getCandidate().getId());
		System.out.println("link2: "+link);
			emailBean.setLink(link);
		}
		catch(Exception ex){ex.printStackTrace();}

		int duration = computeDuration(test);
		emailBean.setDuration(duration);

		dataItemId.setValue(test);
		
		//String link = candidateBean.generateLink(test.getCandidate().getId());
		
		emailBean.setInterviewDto(test);
		
		//initialize emailBean

		emailBean.setEmployeeId(employeeid);
		emailBean.setIdto(interviewController.getIdto());
		emailBean.setSelectedRoomID(test.getRoom().getId());
		emailBean.setSelectedTemplateID(test.getTemplate().getId());
		emailBean.setIdCandidate(test.getCandidate().getId());

		//redirect to emailCandidateContent page
		
		
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/emailCandidateContent.xhtml");
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("send was clicked " + test.getId());

	}

	//show detail of candidate
	public void showCandidate() {
		//get selected candidate
		 candidate = (CandidateViewDto) mainTable.getRowData();
		try {
			//for each interview of the candidate
			for (InterviewViewDto in : candidate.getInterviews()) {	
				if (in.getTaken()){
				//compute its score
				float score = scoreBean.computeTotalScore(in.getId());
				in.setScore(score);			
				intervShowCandidate.add(in);
				}
			}
			System.out.println("name: "+candidate.getName());
			//redirect to showCandidate page
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/showCandidate.xhtml");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//detail a test when user clicks on "View Test"
	@SuppressWarnings("unchecked")
	public void detailTest() {
		test = (InterviewViewDto) testNameTable.getRowData();

		try {
			//create a map of key category name and of value of arraylist, where the figures are stored
			Map<String, ArrayList<Float>> mp = new HashMap<String, ArrayList<Float>>();
			List<TestQuestionDTO> answers = testQuestionBean.getInterviewQuestions(test.getId());
			
			//for each question
			for (TestQuestionDTO q : answers) {
				//get the category name it is part of
				String catName = q.getQuestion().getCategory().getName();
				String correctAnswer = Integer.toString(q.getQuestion().getCorrectAnswers());
				String candidateAnswer = Integer.toString(q.getCandidateAnswer());
				
				//compute score for question
				float score = scoreBean.getPointsForQuestion(correctAnswer,candidateAnswer);
				//if the key is already stored in the map modify its contents
				if (mp.containsKey(catName)) {
					ArrayList<Float> categoryScore = mp.get(catName);
					float cscore = categoryScore.get(0);
					float nr = categoryScore.get(1);
					cscore += score;
					nr++;
					categoryScore.set(0, cscore);
					categoryScore.set(1, nr);
					mp.put(catName, categoryScore);
				//else add a new entry 
				} else {
					ArrayList<Float> list = new ArrayList<Float>();
					list.add(score);
					list.add(new Float(1));
					mp.put(catName, list);
				}
			}
			
			// Get a set of the entries
			Set set = mp.entrySet();
			Iterator i = set.iterator();
			// Compute prcentage of category questions and percentage of correct questions for each element
			while (i.hasNext()) {
				Map.Entry me = (Map.Entry) i.next();
				ArrayList<Float> catScore = (ArrayList<Float>) me.getValue();
				float percentage = Math.round((catScore.get(0)) * 100
						/ catScore.get(1) * 10) / 10;
				float catPercentage = Math.round(catScore.get(1)
						/ answers.size() * 100 * 10) / 10;
				catScore.add(percentage);
				catScore.add(catPercentage);

			}
			//initialize testDetailsBean
			ArrayList<Map<String, ArrayList<Float>>> entrySet = new ArrayList(mp.entrySet());
			testDetailsBean.setEntrySet(entrySet);
			testDetailsBean.setCandidateName(test.getCandidate().getFirstName()+ " " + test.getCandidate().getLastName());
			testDetailsBean.setDate(format(test.getDate()));
			testDetailsBean.setRoom(test.getRoom().getAddress());
			testDetailsBean.setScore(Math.round(scoreBean.computeTotalScore(test.getId())/answers.size()*100));
			testDetailsBean.setTestName(test.getTemplate().getTitle());

			//redirect to viewTestDetails page
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/viewTestDetails.xhtml");
		} catch (Exception e) {

			e.printStackTrace();
		}

	}

	// initializes the InterviewController and redirects to addInterview.xhtml
	public void addTest() {
		System.out.println("Entered addTest");
		candidate = (CandidateViewDto) mainTable.getRowData();
		System.out.println("Set candidate");
		//initialize interviewController
		interviewController.setCandidate(candidate);
		interviewController.setEmployeeId(employeeid);
		System.out.println("Set employee");
		interviewController.setErrorMessage("");
		System.out.println("error");
		
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/addTest.xhtml");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public ArrayList<CandidateViewDto> getCandidates() {
		return candidates;
	}

	// get candidate by id
	public ArrayList<CandidateViewDto> getCandidatesById() {
		candidatesById = (ArrayList<CandidateViewDto>) candidateBean
				.getCandidatesById(1);
		return candidatesById;
	}

	//  button to testerhome page from Send Email	
	public void backFromSend() { 
		if (emailBean.getInterviewDto()!=null){
		test= emailBean.getInterviewDto();
		if (emailBean.getDelete()) {  
			initCandidates();
		
			test.setDelete(true);
			test.setSend(true);
			test.setView(false);
			test.setButDel("buttonDis");
			test.setButSend("buttonDis");
			test.setButView("button");
			/*//set buttons
			 * 
			test.setDelete(false);
			test.setSend(false);
			test.setView(true);
			test.setButDel("button");
			test.setButSend("button");
			test.setButView("buttonDis");*/

		}
		
		/*else {
			test.setDelete(true);
			test.setSend(true);
			test.setView(false);
			test.setButDel("buttonDis");
			test.setButSend("buttonDis");
			test.setButView("button");
		} 
		if (!emailBean.getInterviewDto().getFromRedirect()){
			test.setDelete(false);
			test.setButDel("button");
		}
		else {
			test.setDelete(true);
			test.setButDel("buttonDis");
		}*/
		if (emailBean.getInterviewDto()!=null)
			emailBean.getInterviewDto().setFromRedirect(false);
		emailBean.setDelete(false);
		}
		//redirect to testerhome
		try {
			FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/testerhome.xhtml");
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	//back button to testerhome page from View button
	public void backFromView(){	
		if (interviewController.getInterviewView()!=null){
		test= interviewController.getInterviewView();
		interviewController.setReschedule(false);	
		if (!test.getFromRedirect())
			initCandidates();
		interviewController.getInterviewView().setFromRedirect(false);}
		System.out.println("Going back");
			try {
				FacesContext.getCurrentInstance().getExternalContext().redirect("/MSGCandidateTesting/faces/testerhome.xhtml");
			} catch (Exception e) {
				e.printStackTrace();
			}	
	}
	//format the date String 
	public String format(String date){
		String result="N/A";
		try{
		String[] s=date.split(" ");
		result= s[0]+" "+s[1]+" "+s[2]+" "+s[5];}
		catch (Exception ex){}
		return result;
	}
	
	public void initCandidates() {
		for (CandidateViewDto c:candidates){
			ArrayList<InterviewViewDto> interv = new ArrayList<InterviewViewDto>();
			ArrayList<InterviewViewDto> interviews = new ArrayList<InterviewViewDto>(); 
			interv=(ArrayList<InterviewViewDto>) c.getInterviews();
			for (InterviewViewDto i: interv){
				System.out.println("title of template is: "+i.getTemplate().getTitle()+" interviewid: "+i.getId()+" and room: "+i.getRoom().getAddress())
				;
					//remove interview from database
			  if ((i.getTemplate().getTitle().equals("You have to add and send a new Interview!"))&& ( (c.getInterviews().size()>1)))
					interviewBean.deleteInterview(i.getId());
				 else interviews.add(i);;
				}
			c.setInterviews(interviews);
		}
		
	}
	
	// setters and getters
	public void setEmployeeid(int employeeid) {
		this.employeeid = employeeid;
	}

	public int getEmployeeid() {
		return employeeid;
	}

	public void setDataTable(HtmlDataTable dataTable) {
		this.dataTable = dataTable;
	}

	public HtmlDataTable getDataTable() {
		return dataTable;
	}

	public void setTest(InterviewViewDto test) {
		this.test = test;
	}

	public InterviewViewDto getTest() {
		return test;
	}

	public void setDataItemId(HtmlInputHidden dataItemId) {
		this.dataItemId = dataItemId;
	}

	public HtmlInputHidden getDataItemId() {
		return dataItemId;
	}

	public void setEmailBean(EmailBean emailBean) {
		this.emailBean = emailBean;
	}

	public EmailBean getEmailBean() {
		return emailBean;
	}

	public void setMainTable(HtmlDataTable mainTable) {
		this.mainTable = mainTable;
	}

	public HtmlDataTable getMainTable() {
		return mainTable;
	}

	public void setCandidate(CandidateViewDto candidate) {
		this.candidate = candidate;
	}

	public CandidateViewDto getCandidate() {
		return candidate;
	}

	public AuthentificationController getAuthentificationController() {
		return authentificationController;
	}

	public void setAuthentificationController(
			AuthentificationController authentificationController) {
		this.authentificationController = authentificationController;
	}

	public void setCorrectBean(CorrectTestBean correctBean) {
		this.correctBean = correctBean;
	}

	public CorrectTestBean getCorrectBean() {
		return correctBean;
	}

	public void setTestNameTable(HtmlDataTable testNameTable) {
		this.testNameTable = testNameTable;
	}

	public HtmlDataTable getTestNameTable() {
		return testNameTable;
	}

	public void setTestDetailsBean(TestDetailsBean testDetailsBean) {
		this.testDetailsBean = testDetailsBean;
	}

	public TestDetailsBean getTestDetailsBean() {
		return testDetailsBean;
	}

	public void setInterviewController(InterviewController interviewController) {
		this.interviewController = interviewController;
	}

	public InterviewController getInterviewController() {
		return interviewController;
	}


	public void setMenuController(MenuController menuController) {
		this.menuController = menuController;
	}

	public MenuController getMenuController() {
		return menuController;
	}


	public void setIntervShowCandidate(ArrayList<InterviewViewDto> intervShowCandidate) {
		this.intervShowCandidate = intervShowCandidate;
	}

	public ArrayList<InterviewViewDto> getIntervShowCandidate() {
		return intervShowCandidate;
	}

	
}
